home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / misc.c < prev    next >
C/C++ Source or Header  |  1999-02-04  |  14KB  |  510 lines

  1. /* $Id: misc.c,v 3.13 1998/07/18 03:33:53 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: misc.c,v $
  26.  * Revision 3.13  1998/07/18 03:33:53  brianp
  27.  * glRead/DrawBuffer() generated GL_INVALID_ENUM instead of GL_INVALID_OPERATION
  28.  *
  29.  * Revision 3.12  1998/06/19 02:37:58  brianp
  30.  * fixed an error code in glReadBuffer()
  31.  *
  32.  * Revision 3.11  1998/06/07 22:18:52  brianp
  33.  * implemented GL_EXT_multitexture extension
  34.  *
  35.  * Revision 3.10  1998/04/22 00:52:42  brianp
  36.  * added GLcontext parameter to driver ExtensionString()
  37.  *
  38.  * Revision 3.9  1998/04/14 00:02:10  brianp
  39.  * fixed bug in which whole buffer might be cleared instead of scissor rect
  40.  *
  41.  * Revision 3.8  1998/03/27 04:39:44  brianp
  42.  * Driver.ExtensionString() must now return complete extension list
  43.  *
  44.  * Revision 3.7  1998/03/19 02:04:22  brianp
  45.  * added GL_SGIS_texture_edge_clamp
  46.  *
  47.  * Revision 3.6  1998/03/15 18:50:25  brianp
  48.  * added GL_EXT_abgr extension
  49.  *
  50.  * Revision 3.5  1998/03/15 18:32:12  brianp
  51.  * applied DavidB's patches for v0.23 of fxmesa driver
  52.  *
  53.  * Revision 3.4  1998/02/20 04:50:44  brianp
  54.  * implemented GL_SGIS_multitexture
  55.  *
  56.  * Revision 3.3  1998/02/01 16:37:19  brianp
  57.  * added GL_EXT_rescale_normal extension
  58.  *
  59.  * Revision 3.2  1998/02/01 15:23:52  brianp
  60.  * added ExtensionString() function to device driver
  61.  *
  62.  * Revision 3.1  1998/01/31 23:58:19  brianp
  63.  * new gl_Clear: removed ClearDepthBuffer and ClearColorAndDepth functions
  64.  *
  65.  * Revision 3.0  1998/01/31 20:59:27  brianp
  66.  * initial rev
  67.  *
  68.  */
  69.  
  70.  
  71. #ifdef PC_HEADER
  72. #include "all.h"
  73. #else
  74. #include <stdlib.h>
  75. #include <string.h>
  76. #include "accum.h"
  77. #include "alphabuf.h"
  78. #include "context.h"
  79. #include "depth.h"
  80. #include "macros.h"
  81. #include "masking.h"
  82. #include "misc.h"
  83. #include "stencil.h"
  84. #include "types.h"
  85. #endif
  86.  
  87.  
  88.  
  89. void gl_ClearIndex( GLcontext *ctx, GLfloat c )
  90. {
  91.    if (INSIDE_BEGIN_END(ctx)) {
  92.       gl_error( ctx, GL_INVALID_OPERATION, "glClearIndex" );
  93.       return;
  94.    }
  95.    ctx->Color.ClearIndex = (GLuint) c;
  96.    if (!ctx->Visual->RGBAflag) {
  97.       /* it's OK to call glClearIndex in RGBA mode but it should be a NOP */
  98.       (*ctx->Driver.ClearIndex)( ctx, ctx->Color.ClearIndex );
  99.    }
  100. }
  101.  
  102.  
  103. #include <stdio.h>
  104. void gl_ClearColor( GLcontext *ctx, GLclampf red, GLclampf green,
  105.             GLclampf blue, GLclampf alpha )
  106. {
  107.    if (INSIDE_BEGIN_END(ctx)) {
  108.       gl_error( ctx, GL_INVALID_OPERATION, "glClearColor" );
  109.       return;
  110.    }
  111.    ctx->Color.ClearColor[0] = CLAMP( red,   0.0F, 1.0F );
  112.    ctx->Color.ClearColor[1] = CLAMP( green, 0.0F, 1.0F );
  113.    ctx->Color.ClearColor[2] = CLAMP( blue,  0.0F, 1.0F );
  114.    ctx->Color.ClearColor[3] = CLAMP( alpha, 0.0F, 1.0F );
  115.  
  116.    if (ctx->Visual->RGBAflag) {
  117.       GLubyte r = (GLint) (ctx->Color.ClearColor[0] * 255.0F);
  118.       GLubyte g = (GLint) (ctx->Color.ClearColor[1] * 255.0F);
  119.       GLubyte b = (GLint) (ctx->Color.ClearColor[2] * 255.0F);
  120.       GLubyte a = (GLint) (ctx->Color.ClearColor[3] * 255.0F);
  121.       (*ctx->Driver.ClearColor)( ctx, r, g, b, a );
  122.    }
  123. }
  124.  
  125.  
  126.  
  127.  
  128. /*
  129.  * Clear the color buffer when glColorMask or glIndexMask is in effect.
  130.  */
  131. static void clear_color_buffer_with_masking( GLcontext *ctx )
  132. {
  133.    GLint x, y, height, width;
  134.  
  135.    /* Compute region to clear */
  136.    if (ctx->Scissor.Enabled) {
  137.       x = ctx->Buffer->Xmin;
  138.       y = ctx->Buffer->Ymin;
  139.       height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
  140.       width  = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
  141.    }
  142.    else {
  143.       x = 0;
  144.       y = 0;
  145.       height = ctx->Buffer->Height;
  146.       width  = ctx->Buffer->Width;
  147.    }
  148.  
  149.    if (ctx->Visual->RGBAflag) {
  150.       /* RGBA mode */
  151.       GLubyte r = (GLint) (ctx->Color.ClearColor[0] * 255.0F);
  152.       GLubyte g = (GLint) (ctx->Color.ClearColor[1] * 255.0F);
  153.       GLubyte b = (GLint) (ctx->Color.ClearColor[2] * 255.0F);
  154.       GLubyte a = (GLint) (ctx->Color.ClearColor[3] * 255.0F);
  155.       GLint i;
  156.       for (i=0;i<height;i++,y++) {
  157.      GLubyte rgba[MAX_WIDTH][4];
  158.      GLint j;
  159.      for (j=0; j<width; j++) {
  160.         rgba[j][RCOMP] = r;
  161.         rgba[j][GCOMP] = g;
  162.         rgba[j][BCOMP] = b;
  163.         rgba[j][ACOMP] = a;
  164.      }
  165.      gl_mask_rgba_span( ctx, width, x, y, rgba );
  166. #ifndef __STORM__
  167.      (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y, rgba, NULL );
  168. #else
  169.      (*ctx->Driver.WriteRGBASpan)( ctx, width, x, y, (CONST GLubyte(*)[4])rgba, NULL );
  170. #endif
  171.      if (ctx->RasterMask & ALPHABUF_BIT) {
  172. #ifndef __STORM__
  173.         gl_write_alpha_span( ctx, width, x, y, rgba, NULL );
  174. #else
  175.         gl_write_alpha_span( ctx, width, x, y, (CONST GLubyte(*)[4])rgba, NULL );
  176. #endif
  177.      }
  178.       }
  179.    }
  180.    else {
  181.       /* Color index mode */
  182.       GLuint indx[MAX_WIDTH];
  183.       GLubyte mask[MAX_WIDTH];
  184.       GLint i, j;
  185.       MEMSET( mask, 1, width );
  186.       for (i=0;i<height;i++,y++) {
  187.      for (j=0;j<width;j++) {
  188.         indx[j] = ctx->Color.ClearIndex;
  189.      }
  190.      gl_mask_index_span( ctx, width, x, y, indx );
  191.      (*ctx->Driver.WriteCI32Span)( ctx, width, x, y, indx, mask );
  192.       }
  193.    }
  194. }
  195.  
  196.  
  197.  
  198. /*
  199.  * Clear the front and/or back color buffers.  Also clear the alpha
  200.  * buffer(s) if present.
  201.  */
  202. static void clear_color_buffers( GLcontext *ctx )
  203. {
  204.    if (ctx->Color.SWmasking) {
  205.       clear_color_buffer_with_masking( ctx );
  206.    }
  207.    else {
  208.       GLint x = ctx->Buffer->Xmin;
  209.       GLint y = ctx->Buffer->Ymin;
  210.       GLint height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
  211.       GLint width  = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
  212.       (void) (*ctx->Driver.Clear)( ctx, GL_COLOR_BUFFER_BIT,
  213.                    !ctx->Scissor.Enabled,
  214.                    x, y, width, height );
  215.       if (ctx->RasterMask & ALPHABUF_BIT) {
  216.      /* front and/or back alpha buffers will be cleared here */
  217.      gl_clear_alpha_buffers( ctx );
  218.       }
  219.    }
  220.  
  221.    if (ctx->RasterMask & FRONT_AND_BACK_BIT) {
  222.       /*** Also clear the back buffer ***/
  223.       (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
  224.       if (ctx->Color.SWmasking) {
  225.      clear_color_buffer_with_masking( ctx );
  226.       }
  227.       else {
  228.      GLint x = ctx->Buffer->Xmin;
  229.      GLint y = ctx->Buffer->Ymin;
  230.      GLint height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
  231.      GLint width  = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
  232.      (void) (*ctx->Driver.Clear)( ctx, GL_COLOR_BUFFER_BIT,
  233.                       !ctx->Scissor.Enabled,
  234.                       x, y, width, height );
  235.       }
  236.       (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
  237.    }
  238. }
  239.  
  240.  
  241.  
  242. void gl_Clear( GLcontext *ctx, GLbitfield mask )
  243. {
  244. #ifdef PROFILE
  245.    GLdouble t0 = gl_time();
  246. #endif
  247.  
  248.    if (INSIDE_BEGIN_END(ctx)) {
  249.       gl_error( ctx, GL_INVALID_OPERATION, "glClear" );
  250.       return;
  251.    }
  252.  
  253.    if (ctx->RenderMode==GL_RENDER) {
  254.       GLint x, y, width, height;
  255.       GLbitfield newMask;
  256.  
  257.       if (ctx->NewState) {
  258.      gl_update_state( ctx );
  259.       }
  260.  
  261.       x = ctx->Buffer->Xmin;
  262.       y = ctx->Buffer->Ymin;
  263.       height = ctx->Buffer->Ymax - ctx->Buffer->Ymin + 1;
  264.       width  = ctx->Buffer->Xmax - ctx->Buffer->Xmin + 1;
  265.  
  266.       /* let device driver try to clear the buffers */
  267.       newMask = (*ctx->Driver.Clear)( ctx, mask, !ctx->Scissor.Enabled,
  268.                       x, y, width, height );
  269. #ifdef BUGFIX
  270.       if ( (mask & GL_COLOR_BUFFER_BIT) &&
  271.        (!(newMask & GL_COLOR_BUFFER_BIT)) &&
  272.        (ctx->RasterMask & ALPHABUF_BIT) )
  273.       {
  274.      gl_clear_alpha_buffers( ctx );
  275.       }
  276. #endif
  277.       if ((mask & GL_COLOR_BUFFER_BIT)
  278.       && ctx->RasterMask & FRONT_AND_BACK_BIT) {
  279.      /*** Also clear the back color buffer ***/
  280.      (*ctx->Driver.SetBuffer)( ctx, GL_BACK );
  281.      (void) (*ctx->Driver.Clear)( ctx, GL_COLOR_BUFFER_BIT,
  282.                       !ctx->Scissor.Enabled,
  283.                       x, y, width, height );
  284.      (*ctx->Driver.SetBuffer)( ctx, GL_FRONT );
  285.       }
  286.  
  287.       if (newMask & GL_COLOR_BUFFER_BIT)
  288.       {
  289.     clear_color_buffers( ctx );
  290.       }
  291.       if (newMask & GL_DEPTH_BUFFER_BIT)
  292.       {
  293.     gl_clear_depth_buffer( ctx );
  294.       }
  295.       if (newMask & GL_ACCUM_BUFFER_BIT)
  296.       {
  297.     gl_clear_accum_buffer( ctx );
  298.       }
  299.       if (newMask & GL_STENCIL_BUFFER_BIT)
  300.       {
  301.     gl_clear_stencil_buffer( ctx );
  302.       }
  303.  
  304. #ifdef PROFILE
  305.       ctx->ClearTime += gl_time() - t0;
  306.       ctx->ClearCount++;
  307. #endif
  308.    }
  309. }
  310.  
  311.  
  312.  
  313. const GLubyte *gl_GetString( GLcontext *ctx, GLenum name )
  314. {
  315.    static char result[1000];
  316.    static char *vendor = "Brian Paul";
  317.    static char *version = "1.2 Mesa 3.0";
  318.    static char *extensions = "GL_EXT_blend_color GL_EXT_blend_minmax GL_EXT_blend_logic_op GL_EXT_blend_subtract GL_EXT_paletted_texture GL_EXT_point_parameters GL_EXT_polygon_offset GL_EXT_vertex_array GL_EXT_texture_object GL_EXT_texture3D GL_MESA_window_pos GL_MESA_resize_buffers GL_EXT_shared_texture_palette GL_EXT_rescale_normal GL_EXT_abgr GL_SGIS_texture_edge_clamp GL_SGIS_multitexture GL_EXT_multitexture";
  319.  
  320.    if (INSIDE_BEGIN_END(ctx)) {
  321.       gl_error( ctx, GL_INVALID_OPERATION, "glGetString" );
  322.       return (GLubyte *) 0;
  323.    }
  324.  
  325.    switch (name) {
  326.       case GL_VENDOR:
  327.      return (GLubyte *) vendor;
  328.       case GL_RENDERER:
  329.      strcpy(result, "Mesa");
  330.      if (ctx->Driver.RendererString) {
  331.         strcat(result, " ");
  332.         strcat(result, (*ctx->Driver.RendererString)());
  333.      }
  334.      return (GLubyte *) result;
  335.       case GL_VERSION:
  336.      return (GLubyte *) version;
  337.       case GL_EXTENSIONS:
  338.      if (ctx->Driver.ExtensionString) {
  339.         /* driver specifies the extensions */
  340.         return (const GLubyte *) (*ctx->Driver.ExtensionString)(ctx);
  341.      }
  342.      else {
  343.         /* return default extensions */
  344.         return (const GLubyte *) extensions;
  345.      }
  346.       default:
  347.      gl_error( ctx, GL_INVALID_ENUM, "glGetString" );
  348.      return (GLubyte *) 0;
  349.    }
  350. }
  351.  
  352.  
  353.  
  354. void gl_Finish( GLcontext *ctx )
  355. {
  356.    /* Don't compile into display list */
  357.    if (INSIDE_BEGIN_END(ctx)) {
  358.       gl_error( ctx, GL_INVALID_OPERATION, "glFinish" );
  359.       return;
  360.    }
  361.    if (ctx->Driver.Finish) {
  362.       (*ctx->Driver.Finish)( ctx );
  363.    }
  364. }
  365.  
  366.  
  367.  
  368. void gl_Flush( GLcontext *ctx )
  369. {
  370.    /* Don't compile into display list */
  371.    if (INSIDE_BEGIN_END(ctx)) {
  372.       gl_error( ctx, GL_INVALID_OPERATION, "glFlush" );
  373.       return;
  374.    }
  375.    if (ctx->Driver.Flush) {
  376.       (*ctx->Driver.Flush)( ctx );
  377.    }
  378. }
  379.  
  380.  
  381.  
  382. void gl_Hint( GLcontext *ctx, GLenum target, GLenum mode )
  383. {
  384.    if (INSIDE_BEGIN_END(ctx)) {
  385.       gl_error( ctx, GL_INVALID_OPERATION, "glHint" );
  386.       return;
  387.    }
  388.    if (mode!=GL_DONT_CARE && mode!=GL_FASTEST && mode!=GL_NICEST) {
  389.       gl_error( ctx, GL_INVALID_ENUM, "glHint(mode)" );
  390.       return;
  391.    }
  392.    switch (target) {
  393.       case GL_FOG_HINT:
  394.      ctx->Hint.Fog = mode;
  395.      break;
  396.       case GL_LINE_SMOOTH_HINT:
  397.      ctx->Hint.LineSmooth = mode;
  398.      break;
  399.       case GL_PERSPECTIVE_CORRECTION_HINT:
  400.      ctx->Hint.PerspectiveCorrection = mode;
  401.      break;
  402.       case GL_POINT_SMOOTH_HINT:
  403.      ctx->Hint.PointSmooth = mode;
  404.      break;
  405.       case GL_POLYGON_SMOOTH_HINT:
  406.      ctx->Hint.PolygonSmooth = mode;
  407.      break;
  408.       default:
  409.      gl_error( ctx, GL_INVALID_ENUM, "glHint(target)" );
  410.    }
  411.    ctx->NewState |= NEW_ALL;   /* just to be safe */
  412. }
  413.  
  414.  
  415.  
  416. void gl_DrawBuffer( GLcontext *ctx, GLenum mode )
  417. {
  418.    if (INSIDE_BEGIN_END(ctx)) {
  419.       gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  420.       return;
  421.    }
  422.    switch (mode) {
  423.       case GL_FRONT:
  424.       case GL_FRONT_LEFT:
  425.       case GL_FRONT_AND_BACK:
  426.      if ( (*ctx->Driver.SetBuffer)( ctx, GL_FRONT ) == GL_FALSE ) {
  427.         gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  428.         return;
  429.      }
  430.      ctx->Color.DrawBuffer = mode;
  431.      ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
  432.      ctx->NewState |= NEW_RASTER_OPS;
  433.      break;
  434.       case GL_BACK:
  435.       case GL_BACK_LEFT:
  436.      if ( (*ctx->Driver.SetBuffer)( ctx, GL_BACK ) == GL_FALSE) {
  437.         gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  438.         return;
  439.      }
  440.      ctx->Color.DrawBuffer = mode;
  441.      ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
  442.      ctx->NewState |= NEW_RASTER_OPS;
  443.      break;
  444.       case GL_NONE:
  445.      ctx->Color.DrawBuffer = mode;
  446.      ctx->Buffer->Alpha = NULL;
  447.      ctx->NewState |= NEW_RASTER_OPS;
  448.      break;
  449.       case GL_FRONT_RIGHT:
  450.       case GL_BACK_RIGHT:
  451.       case GL_LEFT:
  452.       case GL_RIGHT:
  453.       case GL_AUX0:
  454.       case GL_AUX1:
  455.       case GL_AUX2:
  456.       case GL_AUX3:
  457.      gl_error( ctx, GL_INVALID_OPERATION, "glDrawBuffer" );
  458.      break;
  459.       default:
  460.      gl_error( ctx, GL_INVALID_ENUM, "glDrawBuffer" );
  461.    }
  462. }
  463.  
  464.  
  465.  
  466. void gl_ReadBuffer( GLcontext *ctx, GLenum mode )
  467. {
  468.    if (INSIDE_BEGIN_END(ctx)) {
  469.       gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
  470.       return;
  471.    }
  472.    switch (mode) {
  473.       case GL_FRONT:
  474.       case GL_FRONT_LEFT:
  475.      if ( (*ctx->Driver.SetBuffer)( ctx, GL_FRONT ) == GL_FALSE) {
  476.         gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
  477.         return;
  478.      }
  479.      ctx->Pixel.ReadBuffer = mode;
  480.      ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha;
  481.      ctx->NewState |= NEW_RASTER_OPS;
  482.      break;
  483.       case GL_BACK:
  484.       case GL_BACK_LEFT:
  485.      if ( (*ctx->Driver.SetBuffer)( ctx, GL_BACK ) == GL_FALSE) {
  486.         gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
  487.         return;
  488.      }
  489.      ctx->Pixel.ReadBuffer = mode;
  490.      ctx->Buffer->Alpha = ctx->Buffer->BackAlpha;
  491.      ctx->NewState |= NEW_RASTER_OPS;
  492.      break;
  493.       case GL_FRONT_RIGHT:
  494.       case GL_BACK_RIGHT:
  495.       case GL_LEFT:
  496.       case GL_RIGHT:
  497.       case GL_AUX0:
  498.       case GL_AUX1:
  499.       case GL_AUX2:
  500.       case GL_AUX3:
  501.      gl_error( ctx, GL_INVALID_OPERATION, "glReadBuffer" );
  502.      break;
  503.       default:
  504.      gl_error( ctx, GL_INVALID_ENUM, "glReadBuffer" );
  505.    }
  506.  
  507.    /* Remember, the draw buffer is the default state */
  508.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  509. }
  510.